<template>
  <div id="home">
    <el-container style="height: 100%">
      <el-aside width="200px"><BaseAside /></el-aside>
      <el-container>
        <el-header><HeaderMenu /></el-header>
        <div
          style="
            background: #ffff;
            margin-top: -10px;
            width: 100%;
            height: 6%;
            padding-top: 10px;
            overflow-x: scroll;
            white-space: nowrap;
          "
        >
          <AppTag />
        </div>
        <el-main style="background: #f6f6f6">
          <router-view></router-view>
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>

<script>
export default {
  name: "HomeView",
  data() {
    return {
      //websocket链接
      ws: {},
      //websocket上线状态
      isSocketOpen: false,
      timeout: 28 * 1000, //30秒一次心跳
      timeoutObj: null, //心跳心跳倒计时
      serverTimeoutObj: null, //心跳倒计时
      timeoutnum: null, //断开 重连倒计时
    };
  },
  components: {
    AppTag: () => import("@/components/AppTag.vue"),
    BaseAside: () => import("@/components/BaseAside.vue"),
    HeaderMenu: () => import("@/components/HeaderMenu.vue"),
  },
  created() {
    //链接websocket
    this.init();
  },
  methods: {
    // 发送消息
    async sendMessage(message) {
      // 检查 WebSocket 连接状态
      if (this.ws.readyState !== 1) {
        // 重新连接 WebSocket
        await this.init();
        // 等待 WebSocket 连接成功
        await new Promise((resolve) => {
          const checkSocketOpen = () => {
            if (this.ws.readyState === 1) {
              resolve();
            } else {
              setTimeout(checkSocketOpen, 100);
            }
          };
          checkSocketOpen();
        });
      }
      this.ws.send(JSON.stringify(message));
    },
    //init函数可在页面加载的时候就进行初始化或者根据自己的业务需求在需要打开通讯的时候在进行初始化
    init() {
      if (this.$store.state.user.userId == null) {
        return;
      }
      // 实例化socket，这里的实例化直接赋值给this.ws是为了后面可以在其它的函数中也能调用websocket方法，例如：this.ws.close(); 完成通信后关闭WebSocket连接
      this.ws = new WebSocket(
        this.$websocketUrl + this.$store.state.user.userId + "/sys"
      );
      this.$websocket.setWs(this.ws);

      //监听是否连接成功
      this.ws.onopen = () => {
        //websocket链接成功
        this.isSocketOpen = true;
        //开启心跳
        this.start();
        //开启事件
        this.$on("init");
      };

      //接听服务器发回的信息并处理展示
      this.ws.onmessage = (res) => {
        let infos = JSON.parse(res.data);
        if (infos.type == "pong") {
          //收到服务器信息，心跳重置
          this.reset();
          return;
        } else if (infos.type == "kicked") {
          //短线
          //弹窗
          this.$message({
            message: "该账号已在其他位置登录，请重新登录!",
            type: "warning",
          });
          window.sessionStorage.clear();
          this.$store.commit(
            "setUser",
            JSON.parse(sessionStorage.getItem("user"))
          );
          this.ws.onclose();
          this.$router.push("/");
        }
        window.dispatchEvent(
          new CustomEvent("onmessageWS", {
            detail: {
              data: res.data,
            },
          })
        );
      };

      //监听连接关闭事件
      this.ws.onclose = () => {
        //监听整个过程中websocket的状态
        this.isSocketOpen = false;
        if (
          this.$store.state.user.userId == null ||
          !this.$store.state.user.userId
        ) {
          return;
        }
        this.reconnect();
      };

      //监听并处理error事件
      this.ws.onerror = function (error) {
        this.isSocketOpen = false;
        if (
          this.$store.state.user.userId == null ||
          !this.$store.state.user.userId
        ) {
          return;
        }
        this.reconnect();
      };
    },

    //重新链接
    reconnect() {
      if (this.isSocketOpen) {
        return;
      }
      //判断userId是否还在
      if (
        this.$store.state.user.userId == null ||
        !this.$store.state.user.userId
      ) {
        return;
      }
      this.isSocketOpen = true;
      //没连接上会一直重连，设置延迟避免请求过多
      this.timeoutnum && clearTimeout(this.timeoutnum);
      this.timeoutnum = setTimeout(() => {
        this.isSocketOpen = false;
        //新连接
        this.init();
      }, 5000);
    },
    //重置心跳
    reset() {
      //重置心跳
      var that = this;
      //清除时间
      clearTimeout(that.timeoutObj);
      clearTimeout(that.serverTimeoutObj);
      //重启心跳
      that.start();
    },
    start() {
      //开启心跳
      var self = this;
      self.timeoutObj && clearTimeout(self.timeoutObj);
      self.serverTimeoutObj && clearTimeout(self.serverTimeoutObj);
      self.timeoutObj = setTimeout(function () {
        //这里发送一个心跳，后端收到后，返回一个心跳消息，
        if (self.ws.readyState == 1) {
          //如果连接正常
          self.ws.send(JSON.stringify({ type: "ping" }));
        } else {
          //否则重连
          self.reconnect();
        }
        self.serverTimeoutObj = setTimeout(function () {
          //超时关闭
          self.ws.close();
        }, self.timeout);
      }, self.timeout);
    },
  },
  beforeDestroy() {
    //关闭websocket
    this.ws.onclose();
  },
};
</script>

<style >  
#home {
  width: 100%;
  height: 100%;
  background-color: aqua;
}
.el-header,
.el-footer {
  background-color: #ffffff;
  color: #333;
}

.el-aside {
  background-color: #333;
  color: #333;
}

.el-main {
  background-color: #e9eef3;
  color: #333;
  height: 100%;
}

body > .el-container {
  margin-bottom: 40px;
}

.el-card__body,
.el-main {
  padding: 10px;
}

.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
}

.el-container:nth-child(7) .el-aside {
}
.text_button {
  color: #2cd3b5; /* 设置按钮里的字体颜色 */
}
.pass_button1 {
  background-color: #ffffff; /* 设置按钮的背景颜色 */
  color: #2cd3b5; /* 设置按钮里的字体颜色 */
  border-color: #2cd3b5; /* 设置按钮的边框颜色 */
}
.pass_button {
  background-color: #f5fff5; /* 设置按钮的背景颜色 */
  color: #2cd3b5; /* 设置按钮里的字体颜色 */
  border-color: #d4f8f1; /* 设置按钮的边框颜色 */
}
.custom-button {
  background-color: #2cd3b5; /* 设置按钮的背景颜色 */
  color: #fff; /* 设置按钮里的字体颜色 */
  border-color: #2cd3b5; /* 设置按钮的边框颜色 */
}
.custom-buttonT {
  background-color: #ffff; /* 设置按钮的背景颜色 */
  color: #2cd3b5; /* 设置按钮里的字体颜色 */
  border-color: #2cd3b5; /* 设置按钮的边框颜色 */
}
.custom-button:active {
  background-color: #ffff; /* 设置按钮的背景颜色 */
  color: #2cd3b5; /* 设置按钮里的字体颜色 */
  border-color: #2cd3b5; /* 设置按钮的边框颜色 */
}
.custom-button:focus,
.custom-button:hover {
  background-color: #ffff; /* 设置按钮的背景颜色 */
  color: #2cd3b5; /* 设置按钮里的字体颜色 */
  border-color: #2cd3b5; /* 设置按钮的边框颜色 */
}
.custom-buttonT:active {
  background-color: #2cd3b5; /* 设置按钮的背景颜色 */
  color: #fff; /* 设置按钮里的字体颜色 */
  border-color: #2cd3b5; /* 设置按钮的边框颜色 */
}
.custom-buttonT:focus,
.custom-buttonT:hover {
  background-color: #2cd3b5; /* 设置按钮的背景颜色 */
  color: #fff; /* 设置按钮里的字体颜色 */
  border-color: #2cd3b5; /* 设置按钮的边框颜色 */
}
/*分页*/
.pageAll {
  margin-top: 30px;
}
.pageAll.el-pagination.is-background .el-pager li:not(.disabled).active {
  background-color: #2cd3b5;
  color: #fff;
}
.pageAll.el-pagination.is-background .el-pager li:not(.disabled):hover {
  color: #2cd3b5;
  background: #fff;
}
.el-radio__input.is-checked .el-radio__inner {
  border-color: #2cd3b5;
  background: #2cd3b5;
}
.el-radio__input.is-checked + .el-radio__label {
  color: #2cd3b5;
}
.el-radio__inner:hover {
  border-color: #2cd3b5;
}
.el-input.is-active .el-input__inner,
.el-input__inner:focus {
  border-color: #2cd3b5;
  outline: 0;
}
.el-button--primary {
  color: #fff;
  background-color: #2cd3b5;
  border-color: #2cd3b5;
}
.el-form-item__label {
  width: 80px;
}
.el-form--inline .el-form-item {
  width: 50%;
  margin-right: 0;
}
.ml-10 {
  margin-left: 10px;
}
.mr-10 {
  margin-right: 10px;
}
.pd-10 {
  padding: 10px 0;
}
.el-radio-button__orig-radio:checked + .el-radio-button__inner {
  color: #fff;
  background-color: #2cd3b5;
  border-color: #2cd3b5;
  box-shadow: -1px 0 0 0 #2cd3b5;
}
.el-checkbox__input.is-checked .el-checkbox__inner,
.el-checkbox__input.is-indeterminate .el-checkbox__inner {
  background-color: #2cd3b5;
  border-color: #2cd3b5;
}

.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 100px;
  height: 100px;
  line-height: 100px;
  text-align: center;
}
.avatar {
  width: 100px;
  height: 100px;
  display: block;
}
</style>
